#include "gkt_board.h"
#include "gkt_debug.h"
#include "factory_reset_common.h"
#include "gkt_factory_reset.h"

#if defined(GKT_CONFIG_FACTORY_RESET_ENABLE) && GKT_CONFIG_FACTORY_RESET_ENABLE	\
	&& (FACTORY_RESET_LOCATION == GKT_MODULE_LOC_BACKBOARD)

#include "gkt_backboard.h"

#define FACTORY_RESET_NOTIFY_INTERVAL_MS	500
#define FACTORY_RESET_NOTIFY_TIMEOUT_MS	\
	(FACTORY_RESET_NOTIFY_INTERVAL_MS + 200)

enum {
	FACTORY_RESET_OP_STATUS = 0,
	FACTORY_RESET_OP_MAX
};

typedef struct _factory_reset_bb {
	int	detected;
	gkt_soft_timer_t	timer_module_notify_timeout;
	int	timer_start;
	gkt_factory_reset_notify	notify;
} factory_reset_bb_s;
static factory_reset_bb_s s_factory_reset_bb;

int gkt_factory_reset_is_detected(void)
{
	return s_factory_reset_bb.detected;
}

static void factory_reset_module_notify_timeout(void *arguments)
{
	if (s_factory_reset_bb.timer_start) {
		s_factory_reset_bb.timer_start = 0;

		if (s_factory_reset_bb.detected) {
			s_factory_reset_bb.detected = 0;
			if (s_factory_reset_bb.notify)
				(*s_factory_reset_bb.notify)(GKT_FACTORY_RESET_TYPE_MAX, 0);
		}
	}
}

enum {
	FACTORY_RESET_STATUS_PRESS = GKT_BB_APP_PACKET_MINSIZE,
	FACTORY_RESET_STATUS_TYPE,
	FACTORY_RESET_STATUS_MAX
};
static void factory_reset_module_notify(int notify_type, 
				const uint8_t *data, int length)
{
	uint8_t opcode, press, type;
	int detected, retval;

	if ((GKT_BB_NOTIFY_PEER == notify_type)
		&& (length >= FACTORY_RESET_STATUS_MAX))
	{
		opcode = data[GKT_BB_APP_PACKET_OPCODE];
		if (FACTORY_RESET_OP_STATUS == opcode) {
			if (s_factory_reset_bb.timer_start) {
				s_factory_reset_bb.timer_start = 0;
				gkt_soft_timer_stop(s_factory_reset_bb.timer_module_notify_timeout);
			}

			detected = data[FACTORY_RESET_STATUS_PRESS] ? 1 : 0;
			type = data[FACTORY_RESET_STATUS_TYPE];
			gkt_info("factory_reset_bb: detected(%d - %u), type(%u)\n",
					s_factory_reset_bb.detected, detected, type);

			if (detected != s_factory_reset_bb.detected) {
				s_factory_reset_bb.detected = detected;
				if (detected) {
					retval = gkt_soft_timer_start(s_factory_reset_bb.timer_module_notify_timeout,
								FACTORY_RESET_NOTIFY_TIMEOUT_MS);
					if (GKT_SUCCESS == retval)
						s_factory_reset_bb.timer_start = 1;
				}

				if (s_factory_reset_bb.notify)
					(*s_factory_reset_bb.notify)((int)type, detected);
			}
		}
	}
}

void gkt_factory_reset_register_notify(
				gkt_factory_reset_notify notify)
{
	s_factory_reset_bb.notify = notify;
}

int gkt_factory_reset_init(void)
{
	int retval;

	s_factory_reset_bb.detected = 0;
	s_factory_reset_bb.notify = NULL;

	s_factory_reset_bb.timer_start = 0;
	s_factory_reset_bb.timer_module_notify_timeout = 
		gkt_soft_timer_create(GKT_SOFT_TIMER_ONCE,
				factory_reset_module_notify_timeout, NULL);
	if (!s_factory_reset_bb.timer_module_notify_timeout) {
		gkt_error("factory_reset_bb: create timer failed!\n");
		return GKT_ECREATE;
	}

	gkt_backboard_register_module(GKT_BB_MODULE_FACTORY_RESET, 
			FACTORY_RESET_OP_MAX, factory_reset_module_notify);
	
	return GKT_SUCCESS;
}

#endif

